<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  

  
  <title>SpringBoot系列-消息(RabbitMQ)（二十） | 海晨忆的博客</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  
  
  
  <meta name="description" content="&amp;emsp;&amp;emsp;大多数应用当中，可通过消息服务中间件来提升系统的异步通信和扩展解耦能力。">
<meta property="og:type" content="article">
<meta property="og:title" content="SpringBoot系列-消息(RabbitMQ)（二十）">
<meta property="og:url" content="https://haichenyi.com/2019/11/27/SpringBoot系列-消息-RabbitMQ-（二十）/index.html">
<meta property="og:site_name" content="海晨忆的博客">
<meta property="og:description" content="&amp;emsp;&amp;emsp;大多数应用当中，可通过消息服务中间件来提升系统的异步通信和扩展解耦能力。">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="https://haichenyi.com/uploads/article/2019-11-27/RabbitMQ流程图.png">
<meta property="og:image" content="https://haichenyi.com/uploads/article/2019-11-27/RabbitMQ管理界面图.png">
<meta property="og:image" content="https://haichenyi.com/uploads/article/2019-11-27/创建交换器.png">
<meta property="og:image" content="https://haichenyi.com/uploads/article/2019-11-27/创建消息队列.png">
<meta property="og:image" content="https://haichenyi.com/uploads/article/2019-11-27/交换器与队列绑定.png">
<meta property="og:image" content="https://haichenyi.com/uploads/article/2019-11-27/发送消息之后的queue.png">
<meta property="og:updated_time" content="2019-11-27T07:12:12.484Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="SpringBoot系列-消息(RabbitMQ)（二十）">
<meta name="twitter:description" content="&amp;emsp;&amp;emsp;大多数应用当中，可通过消息服务中间件来提升系统的异步通信和扩展解耦能力。">
<meta name="twitter:image" content="https://haichenyi.com/uploads/article/2019-11-27/RabbitMQ流程图.png">
  
    <link rel="alternate" href="/atom.xml" title="海晨忆的博客" type="application/atom+xml">
  
  
    <link rel="icon" href="/uploads/artistic_image/head.jpg">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  <link rel="stylesheet" href="/css/style.css">
  <link rel="stylesheet" href="/css/highlight.css">
  <script>
  let antiquityStorage = window.sessionStorage.getItem('antiquitySessionStorage');
  if (antiquityStorage == '' || antiquityStorage == null) {
    var antiquityLoader = '<div id="loaderbox"><div class="loader"><div class="load-roll"><div class="load-top"></div><div class="load-right"></div><div class="load-bottom"></div></div></div></div>';
    document.write(antiquityLoader);
    document.body.style.overflow = 'hidden'
  }
  </script>
</head>

<body>
  <div id="fullpage" class="mobile-nav-right">
    
      <div id="wrapper" style="background-image: url(/uploads/artistic_image/bg.jpg)" title="背景图片来自网络">
    
    
      <header id="header">
  <div id="nav-toggle" class="nav-toggle"></div>
  <div class="head-box global-width">
    <nav class="nav-box nav-right">
      
        <a class="nav-item" href="/" title
        
        >首页</a>
      
        <a class="nav-item" href="/archives" title
        
        >归档</a>
      
        <a class="nav-item" href="/about" title
        
        >简历</a>
      
    </nav>
  </div>
</header>
      <div id="middlecontent" title class="global-width sidebar-left">
        <section id="main"><article id="post-SpringBoot系列-消息-RabbitMQ-（二十）" class="article global-container article-type-post" itemscope itemprop="blogPost">
  
    <header class="article-header">
      
  
    <h1 class="article-title" itemprop="name">
      SpringBoot系列-消息(RabbitMQ)（二十）
    </h1>
  

    </header>
  
  <div class="article-meta">
    <a href="/2019/11/27/SpringBoot系列-消息-RabbitMQ-（二十）/" class="article-date">
  <time datetime="2019-11-27T06:44:45.000Z" itemprop="datePublished">2019-11-27</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/Java-SpringBoot/">Java -SpringBoot</a>
  </div>

    
  </div>
  
    <span id="busuanzi_container_page_pv">
      本文总阅读量<span id="busuanzi_value_page_pv"></span>次
    </span>
  

  <div class="article-inner">
    
    <div class="article-content article-content-cloud doorframe mac" itemprop="articleBody">
      
        <p>&emsp;&emsp;大多数应用当中，可通过消息服务中间件来提升系统的异步通信和扩展解耦能力。</p>
<a id="more"></a>
<h2 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h2><p>消息服务中两个重要的概念</p>
<p>&emsp;&emsp;<strong>消息代理</strong>和<strong>目的地</strong>：当消息发送者发送消息之后，将由消息代理接管，消息代理保证消息发送到指定的目的地。</p>
<p>消息发送的两种方式：</p>
<ol>
<li>队列(Queue)：点对点消息通信(point-to-point)</li>
<li>主题(Topic)：发布(publish)/订阅(subscribe)式消息通信</li>
</ol>
<p>&emsp;&emsp;开始说了，消息可以提升系统的异步通信和扩展解耦能力。异步通信，我们之前讲异步任务的时候已经说过了。给用户发送邮件就是最好，最直接的例子。</p>
<p>&emsp;&emsp;至于，扩展解耦能力，最好最直接的例子就是流量削峰，举个例子：整点秒杀。库存只有100件，用户有10000个人，整点用户讲发送10000个请求，难道每个都请求数据库吗？这个时候，我们就可以做个限制，用户发送的请求先到消息队列，然后，再由消息队列统一管理，哪些请求时可以到数据库的，哪些请求时不可以到数据库的，这样就解决了数据库的抗压能力。</p>
<h2 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h2><p>&emsp;&emsp;点对点式</p>
<ul>
<li>消息发送者发送消息之后，消息代理将消息放在一个队列当中，消息接收者从队列中获取消息内容，消息读取后移除队列</li>
<li>消息只有唯一的发送者和接收者，但并不是说只能有一个接收者</li>
</ul>
<p>&emsp;&emsp;发布订阅式</p>
<ul>
<li>发送者(发布者)发送消息到主题(topic)，多个接收者(订阅者)监听(订阅)这个主题，那么，就会在消息到达的同时收到消息</li>
</ul>
<p><strong>JMS和AMQP</strong></p>
<ul>
<li>JMS:Java message service ：Java消息服务基于JVM消息代理规范，ActiveMQ,HornetMQ就是JMS的实现</li>
<li>AMQP:advanced message Queue Protocol：高级消息队列协议，也是消息代理的规范，兼容JMS，RabbitMQ就是AMQP的实现。</li>
</ul>
<p><strong>对比</strong></p>
<table>
<thead>
<tr>
<th style="text-align:left">类型</th>
<th style="text-align:left">JMS</th>
<th style="text-align:left">AMQP</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">定义</td>
<td style="text-align:left">Java api</td>
<td style="text-align:left">网络线级协议</td>
</tr>
<tr>
<td style="text-align:left">跨语言</td>
<td style="text-align:left">否</td>
<td style="text-align:left">是</td>
</tr>
<tr>
<td style="text-align:left">跨平台</td>
<td style="text-align:left">否</td>
<td style="text-align:left">是</td>
</tr>
<tr>
<td style="text-align:left">model</td>
<td style="text-align:left">提供两种消息模式：peer-2-peer，pub/sub</td>
<td style="text-align:left">提供五种消息模式：direct exchange，fanout exchange，topic change，headers exchange，system exchange。本质来讲，后四种和JMS的pub/sub模型没有太大差别，仅是在路由机制上做了更详细的划分</td>
</tr>
<tr>
<td style="text-align:left">支持消息类型</td>
<td style="text-align:left">多种消息类型：TextMessage，MapMessage，BytesMessage，StreamMessage，ObjectMessage，Message （只有消息头和属性）</td>
<td style="text-align:left">byte[]类型，当实际应用中有复杂消息时，可以序列化之后再发送</td>
</tr>
<tr>
<td style="text-align:left">综合评价</td>
<td style="text-align:left">JMS定义了java api层面的标准，在Java体系中，多个client均可通过JMS进行交互，不需要修改代码，但是其对跨平台支持较差</td>
<td style="text-align:left">AMQP天然具有跨平台，跨语言特性</td>
</tr>
</tbody>
</table>
<h2 id="RabbitMQ"><a href="#RabbitMQ" class="headerlink" title="RabbitMQ"></a>RabbitMQ</h2><h3 id="简介-1"><a href="#简介-1" class="headerlink" title="简介"></a>简介</h3><p>&emsp;&emsp;RabbitMQ是一个由erlang开发的AMQP(Advanved Message Queue Protocol)的开源实现。</p>
<h3 id="核心概念"><a href="#核心概念" class="headerlink" title="核心概念"></a>核心概念</h3><p><strong>Message</strong></p>
<p>&emsp;&emsp;消息，消息是不具名的，它由消息头和消息体组成。消息体是不透明的，而消息头则由一系列的可选属性组成，这些属性包括routing-key（路由键）、priority（相对于其他消息的优先权）、delivery-mode（指出该消息可能需要持久性存储）等</p>
<p><strong>Publisher</strong></p>
<p>&emsp;&emsp;消息的生产者，也是一个向交换器发布消息的客户端应用程序</p>
<p><strong>Exchange</strong></p>
<p>&emsp;&emsp;交换器，用来接收生产者发送的消息并将这些消息路由给服务器中的队列。Exchange有4种类型：direct(默认)，fanout,topic,和headers，不同类型的Exchange转发消息的策略有所区别。</p>
<p><strong>Queue</strong></p>
<p>&emsp;&emsp;消息队列，用来保存消息直到发送给消费者。它是消息的容器，也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面，等待消费者连接到这个队列将其取走。</p>
<p><strong>Binding</strong></p>
<p>&emsp;&emsp;绑定，用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则，所以可以将交换器理解成一个由绑定构成的路由表。Exchange 和Queue的绑定可以是多对多的关系。</p>
<p><strong>Connection</strong></p>
<p>&emsp;&emsp;网络连接，比如一个TCP连接。</p>
<p><strong>Channel</strong></p>
<p>&emsp;&emsp;信道，多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内的虚拟连接，AMQP 命令都是通过信道发出去的，不管是发布消息、订阅队列还是接收消息，这些动作都是通过信道完成。因为对于操作系统来说建立和销毁TCP都是非常昂贵的开销，所以引入了信道的概念，以复用一条 TCP 连接。</p>
<p><strong>Consumer</strong></p>
<p>&emsp;&emsp;消息的消费者，表示一个从消息队列中取得消息的客户端应用程序。</p>
<p><strong>Virtual Host</strong></p>
<p>&emsp;&emsp;虚拟主机，表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。每个 vhost 本质上就是一个 mini 版的 RabbitMQ 服务器，拥有自己的队列、交换器、绑定和权限机制。vhost 是 AMQP 概念的基础，必须在连接时指定，RabbitMQ 默认的 vhost 是 / 。</p>
<p><strong>Broker</strong></p>
<p>&emsp;&emsp;表示消息队列服务器实体</p>
<p><img src="/uploads/article/2019-11-27/RabbitMQ流程图.png" alt="RabbitMQ流程图.png"></p>
<p><strong>流程</strong></p>
<p>&emsp;&emsp;AMQP的消息路由过程跟JMS存在一些差异，增加了Exchange和Binding的角色</p>
<p>JMS流程：</p>
<ol>
<li>生产者(publisher)生成某个消息(Message)，发送到某个队列(Queue)上</li>
<li>消费者(Consumer)监听这个队列(Queue)，消费消息</li>
</ol>
<p>RabbitMQ流程：</p>
<ol>
<li>生产者(publisher)生成某个消息(Message)，把这个消息发送给我们的消息代理服务器上(Broker)</li>
<li>服务器收到消息之后，把这个消息给到一个合适的交换器(Exchange),(服务器有非常多的交换器)</li>
<li>交换器(Exchange)收到这个消息之后，根据路由键(Binding绑定关系)把这个消息给一个或者多个消息队列(Queue)(服务器有很多个消息队列)</li>
<li>消费者(Consumer)连接上队列之后取出消息</li>
</ol>
<p><strong><em>重点就是：交换器和队列的绑定</em></strong></p>
<p><strong><em>重点就是：交换器和队列的绑定</em></strong></p>
<p><strong><em>重点就是：交换器和队列的绑定</em></strong></p>
<p>&emsp;&emsp;我们上面说了Exchange有4种，不同类型转发的消息策略不同，那么，这个策略是什么呢？其中，header和direct交换器完全一致，但是header性能上差很多，基本上不用了</p>
<p><strong><em>重点start</em></strong></p>
<ul>
<li>direct交换器：当我们发送消息时的路由键和绑定中的key完全一致的时候，交换器就将消息发送到该队列当中。它时完全匹配单播模式</li>
<li>fanout交换器：当我们消息发送到fanout交换器时，不管交换器与队列绑定的路由键时什么，fanout交换器都会把这个消息发送给每一个队列，跟UDP广播类似，fanout交换器发送消息最快。</li>
<li>topic交换器：该交换器允许我们对路由键做模糊匹配，有选择性的发送给某一个或者多个队列。两个通配符:井号(#)和星号(*)。其中：井号：匹配0个或者多个单词。星号：匹配一个单词。</li>
</ul>
<p><strong><em>重点end</em></strong></p>
<h3 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h3><p>&emsp;&emsp;首先，打开我们的虚拟机，用SecureCRT连接我们的虚拟机，我用的SecureCRT，至于你用的啥连接虚拟机，随便你。</p>
<p>&emsp;&emsp;然后，用docker安装带manager版本的rabbit，带manager的版本自带图形化界面，容易操作。从docker hub上面搜索，我安装的是</p>
<div class="highlight-box"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker pull rabbitmq:3.8.1-management</span><br></pre></td></tr></table></figure></div>
<p>&emsp;&emsp;接着，新建容器，记得带端口号,-d后台运行，映射两个端口号，起自己的名字，加上镜像id</p>
<div class="highlight-box"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -d -p 5672:5672 -p 15672:15672 --name myrabbitmq 镜像id</span><br></pre></td></tr></table></figure></div>
<p>&emsp;&emsp;接下来，就可以访问了，通过虚拟机的ip地址加上端口号，账号密码都是guest</p>
<div class="highlight-box"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">虚拟机ip地址:15672</span><br></pre></td></tr></table></figure></div>
<p><img src="/uploads/article/2019-11-27/RabbitMQ管理界面图.png" alt="RabbitMQ管理界面图.png"></p>
<p>&emsp;&emsp;我们在图上，就能看到我们前面说过的：Connection，Channel，Exchange，Queue等等。</p>
<p>&emsp;&emsp;最后面那个admin，我们能够设置用户名和密码，就是我们前面登录的guest，并且，能够设置访问的Virtual Hosts。</p>
<p>&emsp;&emsp;我们看一下最上面的流程图和消息发送流程<br>，我就举一个例子：</p>
<ol>
<li>首先，我们先创建一个交换器名字叫：haichenyi</li>
</ol>
<p><img src="/uploads/article/2019-11-27/创建交换器.png" alt="创建交换器.png"></p>
<ol>
<li>其次，我们再创建一个队列，名字也叫：haichenyi</li>
</ol>
<p><img src="/uploads/article/2019-11-27/创建消息队列.png" alt="创建消息队列.png"></p>
<ol>
<li>接着，我们将这交换器和队列绑定到一起</li>
</ol>
<p><img src="/uploads/article/2019-11-27/交换器与队列绑定.png" alt="交换器与队列绑定.png"></p>
<ol>
<li><p>然后，我们随便发送一条消息</p>
</li>
<li><p>最后，查看消息队列</p>
</li>
</ol>
<p><img src="/uploads/article/2019-11-27/发送消息之后的queue.png" alt="发送消息之后的queue.png"></p>
<p>PS：</p>
<ul>
<li>我们在创建Exchange和Queue的时候，有一个选项：Durability，意思是是否可持久化，也就是，服务器重启之后这个东西是否还存在。就选默认的durable就行了，可持久化的</li>
<li>我们在Exchange和Queue绑定的时候，发送消息的时候，都要填一个Routing key，就是上文我们说的绑定规则。</li>
</ul>
<p>&emsp;&emsp;这就是整个流程，这都是页面操作，下面说一下代码里面怎么写，很简单。</p>
<h3 id="用法"><a href="#用法" class="headerlink" title="用法"></a>用法</h3><p>&emsp;&emsp;首先，添加依赖：</p>
<div class="highlight-box"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&lt;dependency&gt;</span><br><span class="line">    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span><br><span class="line">    &lt;artifactId&gt;spring-boot-starter-amqp&lt;/artifactId&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br></pre></td></tr></table></figure></div>
<p>&emsp;&emsp;然后，就是配置：两个可能出错的位置，我已经注释标明了</p>
<div class="highlight-box"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">spring.rabbitmq.host=192.168.113.22</span><br><span class="line">#这里端口号要用5672，不能用15672，15672是后台管理页面的端口号</span><br><span class="line">spring.rabbitmq.port=5672</span><br><span class="line">#这里的用户民和密码还有virtual-host要对应上，新建的账号要记得给权限</span><br><span class="line">spring.rabbitmq.username=guest</span><br><span class="line">spring.rabbitmq.password=guest</span><br><span class="line">spring.rabbitmq.virtual-host=/</span><br></pre></td></tr></table></figure></div>
<p>&emsp;&emsp;代码怎么写呢？</p>
<div class="highlight-box"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">@SpringBootTest</span><br><span class="line">class SellApplicationTests &#123;</span><br><span class="line"></span><br><span class="line">    @Autowired</span><br><span class="line">    RabbitTemplate rabbitTemplate;</span><br><span class="line"></span><br><span class="line">    @Test</span><br><span class="line">    void contextLoads() &#123;</span><br><span class="line">        //message需要自己构造一个；定义消息体内容和消息头</span><br><span class="line">        //rabbitTemplate.send(exchange,routingKey,message);</span><br><span class="line"></span><br><span class="line">        //Object默认当成消息体，只需传入要发送的对象，自动序列化发送给RabbitMQ</span><br><span class="line">        //rabbitTemplate.convertAndSend(exchange,routingKey,Object);</span><br><span class="line">        </span><br><span class="line">        //对象会被默认序列化之后发送</span><br><span class="line">        User user = new User(&quot;海晨忆&quot;,25);</span><br><span class="line">        rabbitTemplate.convertAndSend(&quot;haichenyi&quot;,&quot;haichenyi&quot;,user);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Test</span><br><span class="line">    void getMsg()&#123;</span><br><span class="line">        //queueName:需要从哪个队列中收消息</span><br><span class="line">        User user = (User) rabbitTemplate.receiveAndConvert(&quot;haichenyi&quot;);</span><br><span class="line">        System.out.println(user.getName());</span><br><span class="line">        System.out.println(user.getAge());</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div>
<p>&emsp;&emsp;可以向上面这样测试，发送和接收。实际应用中，我们要向下面这样写：</p>
<ul>
<li>启动类上添加@EnableRabbit注释，开启Rabbit监听功能</li>
<li>在我们接收的方法添加@RabbitListener注解，queues是一个数组，方法的参数是发送的数据类型。</li>
</ul>
<div class="highlight-box"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">@Service</span><br><span class="line">public class UserService &#123;</span><br><span class="line"></span><br><span class="line">    @RabbitListener(queues = &quot;haichenyi&quot;)</span><br><span class="line">    public void receive(User user)&#123;</span><br><span class="line">        System.out.println(&quot;收到消息：&quot;+user);</span><br><span class="line">        System.out.println(user.getName());</span><br><span class="line">        System.out.println(user.getAge());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div>
<p>&emsp;&emsp;以上，就是RabbitMQ的简单使用了，上面的Exchange，Queue都是在管理界面创建绑定的，代码里面怎么创建绑定呢？</p>
<div class="highlight-box"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">@Autowired</span><br><span class="line">    RabbitAdmin rabbitAdmin;</span><br><span class="line"></span><br><span class="line">    @Test</span><br><span class="line">    void createExchange()&#123;</span><br><span class="line">        //以declare开头的都是创建，这里是创建一个Exchange，需要传一个Exchange对象</span><br><span class="line">        //我们点击过去看，是一个接口，我们就看它的实现类。可以看到5种实现类</span><br><span class="line">        rabbitAdmin.declareExchange(new DirectExchange(&quot;wang.exchange&quot;));</span><br><span class="line">        //创建一个queue队列</span><br><span class="line">        rabbitAdmin.declareQueue(new Queue(&quot;wang.queue&quot;));</span><br><span class="line">        //destination：目的地</span><br><span class="line">        //Binding.DestinationType destinationType：类型,枚举类：队列和交换器两种</span><br><span class="line">        //exchange：交换器</span><br><span class="line">        //routingKey：路由键</span><br><span class="line">        //arguments：头信息</span><br><span class="line">        //绑定有两种绑定方式，一种是把交换器往队列上面绑定，一种是把队列往交换器上面绑定</span><br><span class="line">        rabbitAdmin.declareBinding(new Binding(&quot;wang.queue&quot;,Binding.DestinationType.QUEUE,&quot;wang.exchange&quot;,&quot;wang.key&quot;,null));</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure></div>
<p>&emsp;&emsp;然后，发消息的操作就跟前面写的一样了</p>

      
    </div>
    
      <footer class="article-footer">
        完
      </footer>
    
  </div>
  
    
<nav id="article-nav">
  <div class="article-nav-block">
    
      <a href="/2021/07/07/Android模拟点击/" id="article-nav-newer" class="article-nav-link-wrap">
        <strong class="article-nav-caption"></strong>
        <div class="article-nav-title">
          
            Android模拟点击
          
        </div>
      </a>
    
  </div>
  <div class="article-nav-block">
    
      <a href="/2019/11/13/SpringBoot系列-Docker（十九）/" id="article-nav-older" class="article-nav-link-wrap">
        <div class="article-nav-title">SpringBoot系列-Docker（十九）</div>
        <strong class="article-nav-caption"></strong>
      </a>
    
  </div>
</nav>

    
  
  
</article>
</section>
        <aside id="sidebar">
  
    <div class="widget-box">
  <div class="avatar-box avatar-item">
    <img class="avatar" src="/uploads/artistic_image/head.jpg" title="头像来自网络"></img>
    <h3 class="avatar-name">
      
        海晨忆
      
    </h3>
    <p class="avatar-slogan">
      先谋生，再谋爱。人间值得，未来可期。
    </p>
  </div>
</div>


  
    
  <div class="widget-box">
    <h3 class="widget-title">分类</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/Android-Socket/">Android -Socket</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-加密算法/">Android -加密算法</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-常用功能/">Android -常用功能</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-框架/">Android -框架</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-源码解析/">Android -源码解析</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-自定义view/">Android -自定义view</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-设计模式/">Android -设计模式</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/JAVA-并发/">JAVA -并发</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Java-SpringBoot/">Java -SpringBoot</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Tomcat/">Tomcat</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/kotlin/">kotlin</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/数据库-JDBC/">数据库 -JDBC</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/数据库-MySQL/">数据库 -MySQL</a></li></ul>
    </div>
  </div>


  
    

  
    
  
    
  <div class="widget-box">
    <h3 class="widget-title">归档</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/07/">July 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/11/">November 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/10/">October 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/09/">September 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/08/">August 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/07/">July 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/06/">June 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/10/">October 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/05/">May 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/03/">March 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/02/">February 2018</a></li></ul>
    </div>
  </div>

  
    
  <div class="widget-box">
    <h3 class="widget-title">最新文章</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2021/07/27/JAVA—公平锁，非公平锁，悲观锁，乐观锁，死锁/">JAVA—公平锁，非公平锁，悲观锁，乐观锁，死锁</a>
          </li>
        
          <li>
            <a href="/2021/07/19/JAVA—线程同步器AQS/">JAVA—线程同步器AQS</a>
          </li>
        
          <li>
            <a href="/2021/07/07/Android模拟点击/">Android模拟点击</a>
          </li>
        
          <li>
            <a href="/2019/11/27/SpringBoot系列-消息-RabbitMQ-（二十）/">SpringBoot系列-消息(RabbitMQ)（二十）</a>
          </li>
        
          <li>
            <a href="/2019/11/13/SpringBoot系列-Docker（十九）/">SpringBoot系列-Docker（十九）</a>
          </li>
        
      </ul>
    </div>
  </div>

  
      <div class="widget-box">
    <h3 class="widget-title">友情链接</h3>
    <div class="widget">
      
        <a class="hrf" style="display: block;" href="https://github.com/haichenyi" title target='_blank'
        >Github</a>
      
        <a class="hrf" style="display: block;" href="https://www.jianshu.com/u/6077ee440c37" title target='_blank'
        >简书</a>
      
        <a class="hrf" style="display: block;" href="https://blog.csdn.net/qq_27634797" title target='_blank'
        >CSDN</a>
      
    </div>
  </div>

  
</aside>
      </div>
      <footer id="footer">
  <div class="foot-box footers global-width">
    &copy;2017-2021 海晨忆 &nbsp;&nbsp;
    <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
    <span id="busuanzi_container_site_pv">阁下是第<span id="busuanzi_value_site_pv"></span>个访客</span>
  </div>
</footer>
      <script src="https://code.jquery.com/jquery-2.0.3.min.js"></script>
<script>
if (!window.jQuery) {
var script = document.createElement('script');
script.src = "/js/jquery-2.0.3.min.js";
document.body.write(script);
}
</script>

  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  <script src="/fancybox/jquery.fancybox.pack.js"></script>


<script src="/js/script.js"></script>



    </div>
    <nav id="mobile-nav" class="mobile-nav-box">
  <div class="mobile-nav-img mobile-nav-top"></div>
  
    <a href="/" class="mobile-nav-link">首页</a>
  
    <a href="/archives" class="mobile-nav-link">归档</a>
  
    <a href="/about" class="mobile-nav-link">简历</a>
  
  <div class="mobile-nav-img  mobile-nav-bottom"></div>
</nav>    
  </div>
</body>
</html>